#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'wshu'
__version__ = '1.0'
"""
    ***********************************
    *  @filename : hashers.py
    *  @Author : wshu
    *  @CodeDate : 2020/4/19 11:10
    *  @Software : PyCharm
    ***********************************
"""
import string
import secrets
import hashlib

UNUSABLE_PASSWORD_PREFIX = '!'  # This will never be a valid encoded hash
DEFAULT_ENTROPY = 16  # number of bytes to return by default

def is_password_usable(encoded):
    """
    Return True if this password wasn't generated by
    User.set_unusable_password(), i.e. make_password(None).
    """
    return encoded is None or not encoded.startswith(UNUSABLE_PASSWORD_PREFIX)

def make_password(password):
    """
    生成密码
    """
    if password is None:
        return UNUSABLE_PASSWORD_PREFIX + string.ascii_letters + string.digits
    hasher = "pbkdf2_sha256$150000$" + encrypt(password)
    return hasher



def check_password(password, encoded):
    """
    检查密码
    """
    if password is None or not is_password_usable(encoded):
        return False
    r = identify_hasher(encoded)
    print(r)


def encrypt(string, nbytes=None):
    """
    :param string: 需要加密的字符
    :param nbytes: 生成盐值是多少位字节
    :return: 盐加密
    """
    if nbytes is None:
        default_num = DEFAULT_ENTROPY
    else:
        default_num = nbytes
    salt_val = secrets.token_bytes(default_num)
    hash_res = hashlib.pbkdf2_hmac('sha256', string.encode('utf-8'), salt_val, 100000)
    urlarg = hash_res.hex()
    return urlarg


def make_safe_url():
    """
    :param string:
    :return: 生成url参数token
    """
    safe_urlarg = secrets.token_urlsafe(16)
    return safe_urlarg

def identify_hasher(encoded):
    """
    Return an instance of a loaded password hasher.

    Identify hasher algorithm by examining encoded hash, and call
    get_hasher() to return hasher. Raise ValueError if
    algorithm cannot be identified, or if hasher is not loaded.
    """
    # Ancient versions of Django created plain MD5 passwords and accepted
    # MD5 passwords with an empty salt.
    if ((len(encoded) == 32 and '$' not in encoded) or
            (len(encoded) == 37 and encoded.startswith('md5$$'))):
        algorithm = 'unsalted_md5'
    # Ancient versions of Django accepted SHA1 passwords with an empty salt.
    elif len(encoded) == 46 and encoded.startswith('sha1$$'):
        algorithm = 'unsalted_sha1'
    else:
        algorithm = encoded.split('$', 1)[0]
    return algorithm

if __name__ == '__main__':
    # shapwd = encrypt('123456')
    # print(shapwd)
    # 2597fcd540eaf689411acde3f5930d2c41abc79d2536015ab8bdb53534abf079
    # urlarg = make_safe_url()
    # print(urlarg)
    password = 'ws123456!@#'
    ps = 'pbkdf2_sha256$150000$igjG25HhnUC3$QtTVSKQkyBtePgV4d7U1MdC7etkKweS/A9Gh76J5n00='
    # ps = ch(password)
    # print(ps)
    # print(len(ps))
    r = identify_hasher(ps)
    print(r)